﻿/**
 * \file jeu.cs
 * \brief le modéle du jeu
 * */
namespace Implementation
{
using interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
    [SerializableAttribute()]
	public class Jeu
	{
		private Joueur player1;

		private Joueur player2;

        private CarteImpl carte;

        private Joueur joueurCourant;

        /**
         * \fn creerJeu
         * \param[in] int taille
         * \breif appelle le bon monteur
         */ 
		public virtual void creerJeu(int taille)
		{
            var  mj = new MonteurJeu2P();
            carte = (CarteImpl) mj.creerPartie(taille, player1, player2);
            player1.mettreAjourUnitCarte();
            player2.mettreAjourUnitCarte();
		}

        public virtual CarteImpl getCarte()
        {
            return carte;
        }

        /**
         * \fn faireTour
         * \brief fait le tour du joueur, et retourne un bool pour savoir si il y a eu victoire
         * \param[in] Joueur
         * \return bool
         */ 
		public virtual bool faireTour(Joueur j)
		{
            j.initialiseMove();//initialise les points de mouvements de toutes les unités du joueur à leur maximum
            j.updateUnite();//augmenter vie des unités qui ont pas fait d'action
            j.plus1Tour();
            j.updateVille();//augmenter la pop et la taille ville selon le cas
            bool victoire = victoireAtteinte(j);

            //changement de joueur courant
            joueurCourant = getEnemie(j);
            return victoire;
		}

        /**
         * \fn victoireAtteinte()
         * \param[in] Joueur
         * \return bool
         */ 
		public virtual bool victoireAtteinte(Joueur player)
		{
            Joueur enemie = getEnemie(player);
            if (enemie.getCivilisation().aEnseignant() || enemie.getCivilisation().aVille())
                return false;
            else
                return true;
		}

        /**
         * \fn getEnemie
         * \brief retourne le joueur enemie de celui passé en paramétre
         * \param[in] Joueur j
         * \return Joueur
         */ 
        public virtual Joueur getEnemie(Joueur j)
        {
            if (j == player1)
                return player2;
            else
                return player1;
        }

        /**
        * \fn saveGame( string path, Jeu j)
        * \brief sauvegarde le jeu en cour
        */
        public static void saveGame( string path, Jeu j)
        {
           
            FileStream stream = File.Create(path);
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            formatter.Serialize(stream, j);
            stream.Close();
        }

        /**
        * \fn loadGame(string path)
        * \brief Charge une partie à partir d'une sauvegarde
        */
        public static Jeu loadGame(string path)
        {
            
            FileStream stream = File.OpenRead(path);
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            Jeu j = (Jeu)formatter.Deserialize(stream);
            stream.Close();
            return j;
        }

        /**
         * \fn getUnitePosition
         * \brief retourne les unités situées à la position donné ou null
         * \param[in] int x
         * \param[in] int y
         * \return List<Unite>
         */
        public virtual List<Unite> getUnitePosition(int x, int y)
        {
            return carte.getUnites(x, y);
        }
        
        /**
         * \fn getVillePosition
         * \brief retourne la ville situé à la position donné ou null
         * \param[in] int x
         * \param[in] int y
         * \return Ville
         */ 
        public virtual Ville getVillePosition(int x, int y)
        {
            List<Ville> lv = player1.getCivilisation().getVilles();
            foreach (Ville v in lv)
            {
                if (v.getX() == x && v.getY() == y)
                    return v;
            }

            lv = player2.getCivilisation().getVilles();
            foreach (Ville v in lv)
            {
                if (v.getX() == x && v.getY() == y)
                    return v;
            }
            return null;
        }

		public Jeu(int taille, Joueur p1, Joueur p2)
        {
            player1 = p1;
            player2 = p2;
            player1.setJeu(this);
            player2.setJeu(this);
            creerJeu(taille);
            joueurCourant = p1;
		}
        public Jeu() { }
        
        public List<Joueur> getJoueurs()
        {
            List<Joueur> jous = new List<Joueur>();
            jous.Add(player1);
            jous.Add(player2);
            return jous;
        }

        public Joueur getJoueurCourant()
        {
            return joueurCourant;
        }

	}
}

